<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>五子棋游戏</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        .game-container {
            position: relative;
            width: 540px;
            height: 540px;
            border: 2px solid #000;
            margin: 0 auto;
        }
        .board {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
        }
        .grid-line {
            stroke: #999;
            stroke-width: 1;
        }
        .circle {
            fill: none;
            stroke: #000;
            stroke-width: 2;
        }
        .black-piece {
            fill: black;
            transition: transform 0.3s ease-in-out;
        }
        .white-piece {
            fill: white;
            transition: transform 0.3s ease-in-out;
        }
        .winning-path {
            stroke: red;
            stroke-width: 4;
            stroke-dasharray: 10, 5;
        }
        .winner-popup {
            display: none;
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background-color: rgba(0, 0, 0, 0.7);
            color: white;
            padding: 20px;
            border-radius: 10px;
            z-index: 1000;
        }
    </style>
</head>
<body>
    <div class="game-container">
        <svg class="board"></svg>
    </div>
    <div class="winner-popup" id="winnerPopup">
        <h2 id="winnerMessage"></h2>
        <button onclick="resetGame()">重新开始</button>
    </div>

    <script>
        const boardSize = 15;
        const cellSize = 36;
        const boardWidth = boardSize * cellSize;
        const boardHeight = boardSize * cellSize;

        let currentPlayer = 'black';
        let gameBoard = Array.from({ length: boardSize }, () => Array(boardSize).fill(null));
        let svgElement = document.querySelector('.board');
        let winnerPopup = document.getElementById('winnerPopup');
        let winnerMessage = document.getElementById('winnerMessage');

        function initBoard() {
            for (let i = 0; i <= boardSize; i++) {
                // 水平线
                svgElement.appendChild(createLine(0, i * cellSize, boardWidth, i * cellSize));
                // 垂直线
                svgElement.appendChild(createLine(i * cellSize, 0, i * cellSize, boardHeight));
            }

            svgElement.addEventListener('click', handleBoardClick);
        }

        function createLine(x1, y1, x2, y2) {
            const line = document.createElementNS("http://www.w3.org/2000/svg", "line");
            line.setAttribute("x1", x1);
            line.setAttribute("y1", y1);
            line.setAttribute("x2", x2);
            line.setAttribute("y2", y2);
            line.classList.add("grid-line");
            return line;
        }

        function handleBoardClick(event) {
            if (document.querySelector('.winning-path')) return;

            const rect = svgElement.getBoundingClientRect();
            const x = event.clientX - rect.left;
            const y = event.clientY - rect.top;

            const col = Math.floor(x / cellSize);
            const row = Math.floor(y / cellSize);

            if (col >= 0 && col < boardSize && row >= 0 && row < boardSize && !gameBoard[row][col]) {
                placePiece(row, col);
                checkWin(row, col);
                currentPlayer = currentPlayer === 'black' ? 'white' : 'black';
            }
        }

        function placePiece(row, col) {
            const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
            circle.setAttribute("cx", col * cellSize + cellSize / 2);
            circle.setAttribute("cy", row * cellSize + cellSize / 2);
            circle.setAttribute("r", cellSize / 2 - 2);
            circle.classList.add("circle", `${currentPlayer}-piece`);
            svgElement.appendChild(circle);

            gameBoard[row][col] = currentPlayer;

            circle.animate([
                { transform: 'scale(0)' },
                { transform: 'scale(1)' }
            ], {
                duration: 300,
                easing: 'ease-out'
            });
        }

        function checkWin(row, col) {
            const directions = [
                [1, 0],   // 水平
                [0, 1],   // 垂直
                [1, 1],   // 右对角
                [1, -1]   // 左对角
            ];

            for (const [dx, dy] of directions) {
                let count = 1;
                let x = col + dx;
                let y = row + dy;

                while (x >= 0 && x < boardSize && y >= 0 && y < boardSize && gameBoard[y][x] === currentPlayer) {
                    count++;
                    x += dx;
                    y += dy;
                }

                x = col - dx;
                y = row - dy;

                while (x >= 0 && x < boardSize && y >= 0 && y < boardSize && gameBoard[y][x] === currentPlayer) {
                    count++;
                    x -= dx;
                    y -= dy;
                }

                if (count >= 5) {
                    showWinAnimation(row, col, dx, dy, count);
                    showWinner(currentPlayer);
                    break;
                }
            }
        }

        function showWinAnimation(row, col, dx, dy, count) {
            const startX = (col - 2 * dx) * cellSize + cellSize / 2;
            const startY = (row - 2 * dy) * cellSize + cellSize / 2;
            const endX = (col + (count - 3) * dx) * cellSize + cellSize / 2;
            const endY = (row + (count - 3) * dy) * cellSize + cellSize / 2;

            const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
            path.setAttribute("d", `M ${startX} ${startY} L ${endX} ${endY}`);
            path.classList.add("winning-path");
            svgElement.appendChild(path);

            path.animate([
                { opacity: 0 },
                { opacity: 1 },
                { opacity: 0.5 },
                { opacity: 1 }
            ], {
                duration: 500,
                iterations: Infinity,
                direction: 'alternate'
            });
        }

        function showWinner(player) {
            winnerMessage.textContent = `${player === 'black' ? '黑方' : '白方'}获胜！`;
            winnerPopup.style.display = 'block';
        }

        function resetGame() {
            svgElement.innerHTML = '';
            winnerPopup.style.display = 'none';
            currentPlayer = 'black';
            gameBoard = Array.from({ length: boardSize }, () => Array(boardSize).fill(null));
            initBoard();
        }

        initBoard();
    </script>
</body>
</html>